package cn.iocoder.yudao.module.shop.convert.appointment;

import cn.iocoder.yudao.module.shop.api.appointment.dto.AppointmentCancelReqDTO;
import cn.iocoder.yudao.module.shop.api.appointment.dto.AppointmentCreateReqDTO;
import cn.iocoder.yudao.module.shop.config.shop;
import cn.iocoder.yudao.module.shop.controller.admin.appointment.vo.AppointmentCancelReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.appointment.vo.AppointmentCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.appointment.vo.AppointmentValidateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.appointment.vo.AppointmentValidateRespVO;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.ShopOrderCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.order.vo.ShopOrderRespVO;
import cn.iocoder.yudao.module.shop.convert.base.UserConvert;
import cn.iocoder.yudao.module.shop.convert.item.ShopItemConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.ShopOrderDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 店铺预约 Convert
 *
 * @author 曹建伟
 */
@Mapper
public interface AppointmentConvert {

    AppointmentConvert INSTANCE = Mappers.getMapper(AppointmentConvert.class);

    default AppointmentCreateReqDTO convert(AppointmentCreateReqVO createReqVO) {
        AppointmentCreateReqDTO dto = new AppointmentCreateReqDTO();
        dto.setMemberId(createReqVO.getMemberId());
        dto.setUserId(createReqVO.getUserId());
        dto.setItemId(createReqVO.getItemId());
        dto.setCount(createReqVO.getCount());
        dto.setTimeIndex(createReqVO.getTimeIndex());
        dto.setDateTime(createReqVO.getDateTime());
        dto.setComment(createReqVO.getComment());
        dto.setTenantId(createReqVO.getTenantId());

        return dto;
    }

    default AppointmentCancelReqDTO convert(AppointmentCancelReqVO cancelReqVO) {
        AppointmentCancelReqDTO dto = new AppointmentCancelReqDTO();
        dto.setOrdreId(cancelReqVO.getOrderId());

        return dto;
    }

    default ShopOrderCreateReqVO convert(AppointmentCreateReqDTO createReqDTO){
        ShopOrderCreateReqVO shopOrderCreateReqVO = new ShopOrderCreateReqVO();
        shopOrderCreateReqVO.setMemberId(createReqDTO.getMemberId());
        shopOrderCreateReqVO.setUserId(createReqDTO.getUserId());
        shopOrderCreateReqVO.setShopItemId(createReqDTO.getItemId());
        shopOrderCreateReqVO.setCount(createReqDTO.getCount());
        shopOrderCreateReqVO.setTimeIndex(createReqDTO.getTimeIndex());
        shopOrderCreateReqVO.setDateTime(createReqDTO.getDateTime());
        shopOrderCreateReqVO.setComment(createReqDTO.getComment());
        shopOrderCreateReqVO.setTenantId(createReqDTO.getTenantId());

        return shopOrderCreateReqVO;
    }

    default AppointmentValidateRespVO convert(Map<Long, AdminUserDO> userMap, Map<Long, List<ShopOrderRespVO>> orderListMap){
        AppointmentValidateRespVO appointmentValidateRespVO = new AppointmentValidateRespVO();
        List<AppointmentValidateRespVO.AppointmentValidateItemRespVO> list = new ArrayList<>();
        for(Long id: userMap.keySet()) {
            AppointmentValidateRespVO.AppointmentValidateItemRespVO item = convert(userMap.get(id), orderListMap.get(id));
            item.setOrders(orderListMap.get(id));
            list.add(item);
        }
        appointmentValidateRespVO.setItems(list);
        return appointmentValidateRespVO;
    }

    default AppointmentValidateRespVO.AppointmentValidateItemRespVO convert(AdminUserDO userDO, List<ShopOrderRespVO> orderDOList) {
        AppointmentValidateRespVO.AppointmentValidateItemRespVO item = new AppointmentValidateRespVO.AppointmentValidateItemRespVO();
        item.setVacate(false);
        item.setForbiddenTimeIndexs(new ArrayList<>());
        item.setUser(UserConvert.INSTANCE.convertUserDO(userDO));

        List<Integer> timeIndexs = new ArrayList<>();
        if(orderDOList == null) {
            for(int i = 0; i< shop.INDEX_COUNT; i++) {
             timeIndexs.add(i);
            }
        } else {
            Set<Integer> appointmentedSet = new HashSet<>();
            orderDOList.forEach(shopOrderDO -> {
                LocalDateTime workTime = shopOrderDO.getStartTime().withHour(shop.HOUR).withMinute(shop.MINUTE).withSecond(0);
                Integer startIndex = (int)Duration.between(workTime, shopOrderDO.getStartTime()).toMinutes()/shop.INTERVAL;
                Integer endIndex = startIndex + (int)Duration.between(shopOrderDO.getStartTime(), shopOrderDO.getEndTime()).toMinutes()/shop.INTERVAL-1;
                for(int i = startIndex; i<= endIndex; i++) {
                    appointmentedSet.add(i);
                }
            });

            for(int i = 0; i<shop.INDEX_COUNT; i++) {
                if(!appointmentedSet.contains(i)) {
                    timeIndexs.add(i);
                }
            }
        }
        item.setTimeIndexs(timeIndexs);

        return item;
    }
}
